#ifndef TYPEFIELD_H
#define TYPEFIELD_H
#include "StompedReality/Base.h"
#include "StompedReality/Core.h"
#include <string>
#include <typeinfo>
#include <vector>
namespace StompedReality
{
namespace type_system
{
/*!
 *
 * \author	Stefan Kazalski
 *
 * \brief	Type field info
 *
 *    Stores field information.
 */
struct DLL_EXPORT TypeField
{
  //! \brief	Name.
  const char* name;

  //! \brief	Type.
  StompedReality::TYPE_ID type;

  //! \brief	Offset.
  size_t offset;

  //! \brief	isList?
  bool list;

  //! \brief	Constructor class field.
  template <typename OBJECT_TYPE, typename FIELD_TYPE>
  TypeField ( const char* name, FIELD_TYPE OBJECT_TYPE::* field )
    : name ( name ),
    type ( StompedReality::hash ( typeid ( FIELD_TYPE ).name( ) ) ),
    list ( false )
  {
    OBJECT_TYPE x;
    offset = ( size_t ) ( ( char* ) &( x.*field ) - ( char* )&x );
  }

  //! \brief	Constructor class field of field.
  template <typename OBJECT_TYPE_A, typename FIELD_TYPE_A, typename OBJECT_TYPE_B, typename FIELD_TYPE_B>
  TypeField ( const char* name, FIELD_TYPE_A OBJECT_TYPE_A::* fieldA, FIELD_TYPE_B OBJECT_TYPE_B::* fieldB   )
    : name ( name ),
    type ( StompedReality::hash ( typeid ( FIELD_TYPE_B ).name( ) ) ),
    list ( false )
  {
    OBJECT_TYPE_A x;
    offset = ( size_t ) ( ( char* ) &( x.*fieldA ) - ( char* )&x );
    OBJECT_TYPE_B y;
    offset += ( size_t ) ( ( char* ) &( y.*fieldB ) - ( char* )&y );
    this->list = false;
  }

  //! \brief	Constructor for std:vector.
  template <typename OBJECT_TYPE, typename FIELD_TYPE>
  TypeField ( const char* name, std::vector<FIELD_TYPE> OBJECT_TYPE::* field )
    : name ( name ),
    type ( StompedReality::hash ( typeid ( FIELD_TYPE ).name( ) ) ),
    list ( true )
  {
    OBJECT_TYPE x;
    offset = ( size_t ) ( ( char* ) &( x.*field ) - ( char* )&x );
  }

  //! \brief	TypeInfo string.
  std::string to_s( );
};
}
}
#endif // TYPEFIELD_H
